package cn.jbt.api.admin.service.impl;

import cn.jbt.api.admin.entity.QSysDictOpt;
import cn.jbt.api.admin.entity.SysDictOpt;
import cn.jbt.api.admin.filter.LoginInfoAccessContext;
import cn.jbt.api.admin.repository.SysDictOptRepository;
import cn.jbt.api.admin.service.ISysDictOptService;
import cn.jbt.common.PageQryParam;
import cn.jbt.common.PageQryResult;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
@AllArgsConstructor
@Slf4j
public class SysDictOptServiceImpl implements ISysDictOptService {

    private final JPAQueryFactory jpaQueryFactory;
    private final SysDictOptRepository sysDictOptRepository;

    @Override
    public PageQryResult<SysDictOpt> getAllByPage(PageQryParam<SysDictOpt> pageQryParam) {
        SysDictOpt qParam = pageQryParam.getParam();
        QSysDictOpt qSysDictOpt = QSysDictOpt.sysDictOpt;

        Predicate predicate = qSysDictOpt.isNotNull().or(qSysDictOpt.isNull());
        if (null != qParam) {
            if (!StringUtils.isEmpty(qParam.getDictLabel())) {
                predicate = ExpressionUtils.and(predicate,
                        qSysDictOpt.dictLabel.contains(qParam.getDictLabel()));
            }
            if (!StringUtils.isEmpty(qParam.getDictValue())) {
                predicate = ExpressionUtils.and(predicate,
                        qSysDictOpt.dictValue.contains(qParam.getDictLabel()));
            }
            if (null != qParam.getStatus()) {
                predicate = ExpressionUtils.and(predicate,
                        qSysDictOpt.status.eq(qParam.getStatus()));
            }
            if (qParam.getDictId() > 0) {
                predicate = ExpressionUtils.and(predicate,
                        qSysDictOpt.dictId.eq(qParam.getDictId()));
            }
        }

        List<SysDictOpt> list = jpaQueryFactory.select(qSysDictOpt)
                .from(qSysDictOpt)
                .where(predicate)
                .orderBy(qSysDictOpt.orderby.asc(), qSysDictOpt.id.desc())
                .offset((pageQryParam.getPage() - 1) * pageQryParam.getSize())
                .limit(pageQryParam.getSize())
                .fetch();

        long total = Optional.ofNullable(jpaQueryFactory.select(qSysDictOpt.id.count())
                .from(qSysDictOpt)
                .where(predicate)
                .fetchOne()
        ).orElse(0L);

        return new PageQryResult<>(list, total);
    }

    @Override
    public List<SysDictOpt> getAll(SysDictOpt sysDictOpt) {
        QSysDictOpt qSysDictOpt = QSysDictOpt.sysDictOpt;

        Predicate predicate = qSysDictOpt.isNotNull().or(qSysDictOpt.isNull());
        if (null != sysDictOpt) {
            if (!StringUtils.isEmpty(sysDictOpt.getDictLabel())) {
                predicate = ExpressionUtils.and(predicate,
                        qSysDictOpt.dictLabel.contains(sysDictOpt.getDictLabel()));
            }
            if (!StringUtils.isEmpty(sysDictOpt.getDictValue())) {
                predicate = ExpressionUtils.and(predicate,
                        qSysDictOpt.dictValue.contains(sysDictOpt.getDictLabel()));
            }
            if (null != sysDictOpt.getStatus()) {
                predicate = ExpressionUtils.and(predicate,
                        qSysDictOpt.status.eq(sysDictOpt.getStatus()));
            }
            if (sysDictOpt.getDictId() > 0) {
                predicate = ExpressionUtils.and(predicate,
                        qSysDictOpt.dictId.eq(sysDictOpt.getDictId()));
            }
        }

        return jpaQueryFactory.select(qSysDictOpt)
                .from(qSysDictOpt)
                .where(predicate)
                .orderBy(qSysDictOpt.orderby.asc(), qSysDictOpt.id.desc())
                .fetch();
    }

    @Override
    public SysDictOpt add(SysDictOpt sysDictOpt) {
        sysDictOpt.setUpdateBy(LoginInfoAccessContext.getLoginInfo().getNickname());
        sysDictOpt.setCreateBy(sysDictOpt.getUpdateBy());
        return sysDictOptRepository.save(sysDictOpt);
    }

    @Override
    public SysDictOpt edit(SysDictOpt sysDictOpt) {
        SysDictOpt newSysDictOpt = sysDictOptRepository.findFirstById(sysDictOpt.getId());
        if (null == newSysDictOpt) {
            throw new RuntimeException("404 NotFound");
        }

        newSysDictOpt.edit(sysDictOpt);
        newSysDictOpt.setUpdateBy(LoginInfoAccessContext.getLoginInfo().getNickname());
        return sysDictOptRepository.save(newSysDictOpt);
    }

    @Override
    public void del(List<Long> ids) {
        sysDictOptRepository.deleteAllByIdInBatch(ids);
    }
}
